// SPDX-License-Identifier: Apache-2.0

package chisel3

import chisel3.internal._
import chisel3.experimental.{IntrinsicModule, OpaqueType, SourceInfo}
import chisel3.internal.sourceinfo.SourceInfoTransform

import scala.language.experimental.macros
import scala.collection.immutable.ListMap

class Disable private[chisel3] (private[chisel3] val value: Bool) {

  final def unary_! : Disable = macro SourceInfoTransform.noArg

  def do_unary_!(implicit sourceInfo: SourceInfo): Disable = new Disable(!this.value)
}

object Disable {

  sealed trait Type

  case object Never extends Type

  case object BeforeReset extends Type

  private[chisel3] def withDisable[T](option: Type)(block: => T): T = {
    val parentDisable = Builder.currentDisable

    Builder.currentDisable = option

    val res = block // execute block

    Builder.currentDisable = parentDisable
    res
  }
}

object withDisable {

  def apply[T](disable: Disable.Type)(block: => T): T = Disable.withDisable(disable)(block)
}

private[chisel3] class HasBeenResetIntrinsic(implicit sourceInfo: SourceInfo)
    extends IntrinsicModule(f"circt_has_been_reset") {
  val clock = IO(Input(Clock())).suggestName("clock")
  val reset = IO(Input(Reset())).suggestName("reset")
  val out = IO(Output(Bool())).suggestName("out")
}
